from flask import Flask, render_template, Response
import cv2
import numpy as np

app = Flask(__name__)
zhi = 0
space = 0


class VideoCamera(object):
    def __init__(self):
        # 通过opencv获取实时视频流
        self.video = cv2.VideoCapture(0)
        self.flag = True

    def __del__(self):
        self.video.release()

    def get_frame(self):
        if self.flag:
            ball_color = 'red'
            color_dist = {'red': {'Lower': np.array([0, 0, 0]), 'Upper': np.array([50, 50, 50])}}
            cap = self.video
            image, pai = process1(ball_color, color_dist, cap)
            # 取平均值
            a = sum(pai) / len(pai)
            # 真实比例
            global zhi
            zhi = a / 340
        else:
            ball_color = 'red'
            color_dist = {'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([60, 255, 255])},
                          'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
                          'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])}
                          }
            cap = self.video
            image, yi = process2(ball_color, color_dist, cap)
            # 取平均值
            average = sum(yi) / len(yi)
            # 真实比例
            global space
            space = average / zhi
        # 因为opencv读取的图片并非jpeg格式，因此要用motion JPEG模式需要先将图片转码成jpg格式图片
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()


def gen(camera):
    while True:
        frame = camera.get_frame()
        # 使用generator函数输出视频流， 每次请求输出的content类型是image/jpeg
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/')
def index():  # put application's code here
    return render_template('index.html')


@app.route('/video_feed1')
def video_feed1():
    return Response(gen(VideoCamera()), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/video_feed2')
def video_feed2():
    camera = VideoCamera()
    camera.flag = False
    return Response(gen(camera), mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(debug=True)


# 返回要处理好的数据pai
def process1(ball_color, color_dist, cap):
    pai = []
    success, image = cap.read()
    if success:
        if image is not None:
            gs_frame = cv2.GaussianBlur(image, (5, 5), 0)
            hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)
            erode_hsv = cv2.erode(hsv, None, iterations=2)
            inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])
            cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
            c = max(cnts, key=cv2.contourArea)
            rect = cv2.minAreaRect(c)
            box = cv2.boxPoints(rect)
            # print(box)
            cv2.drawContours(image, [np.int0(box)], -1, (0, 255, 255), 2)
            area = cv2.contourArea(np.int0(box))
            pai.append(area)
            return image, pai


def process2(ball_color, color_dist, cap):
    yi = []
    ww = []
    hh = []
    success, image = cap.read()
    if success:
        if image is not None:
            gs_frame = cv2.GaussianBlur(image, (5, 5), 0)
            hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)
            erode_hsv = cv2.erode(hsv, None, iterations=2)
            inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])
            cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
            c = max(cnts, key=cv2.contourArea)
            rect = cv2.minAreaRect(c)
            box = cv2.boxPoints(rect)
            # print(box)
            cv2.drawContours(image, [np.int0(box)], -1, (0, 255, 255), 2)
            area = cv2.contourArea(np.int0(box))
            yi.append(area)
            x, y, w, h = cv2.boundingRect(np.int0(box))
            ww.append(w)
            hh.append(h)
            return image, yi
